package com.tianhai.web;

import com.tianhai.pojo.Plan;
import com.tianhai.pojo.PlanVo;
import com.tianhai.pojo.PlanVo2;
import com.tianhai.utils.DynamicChangeAnnoUtil;
import com.tianhai.utils.EasyPoiUtil;
import com.tianhai.utils.Result;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.*;

@RestController
@CrossOrigin
@RequestMapping("/excels")
public class ExcelProcessController {
    // 上传成功标志 true：成功；false：失败
    private Boolean flag = false;

    // 获得最初和最新数据集合
    private Map<String, List<Plan>> planMap = new HashMap<>();


    // 获得完整最初数据（null值已处理）
    private List<Plan> fullOldListData;

    // 获得完整最新数据（null值已处理）
    private List<Plan> fullNewListData;

    // 文件名
    private String fileFullName = "";

    // oldName
    private String oldName = "";

    // newName
    private String newName = "";

    /**
     * 文件上传
     * @param file 文件对象
     * @return 返回结果集
     */
    @PostMapping("/uploadFile")
    public Result uploadFile(@RequestParam("file") MultipartFile file) {
        // 需要先进行更改实体类中属性对应的注解值
        try {
            DynamicChangeAnnoUtil.changeAnnoValue();
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }

        // 文件名
        fileFullName = file.getOriginalFilename();
        // 文件名进行切割
        List<String> nameList = Arrays.asList(fileFullName.split("="));

        // 获得命名部分包括后缀名
        String fileNameExts = nameList.get(nameList.size() - 1);

        // 文件名二次切割
        List<String> fileNameAndExt = Arrays.asList(fileNameExts.split("\\."));

        boolean f1 = false;
        boolean f2 = false;

        // 判断文件名
        if ("new".equals(fileNameAndExt.get(0))) { // 如果文件名中存在new值，获得的数据存 map key为 new 的集合中
            planMap.put(fileFullName, EasyPoiUtil.importExcel(file, 1, 1, Plan.class));
            newName = fileFullName;
            f1 = true;
        }

        if ("old".equals(fileNameAndExt.get(0))) { // 如果文件名中存在new值，获得的数据存 map key为 old 的集合中
            planMap.put(fileFullName, EasyPoiUtil.importExcel(file, 1, 1, Plan.class));
            oldName = fileFullName;
            f2 = true;
        }

        if (f1 == true || f2 == true) {
            flag = true;
        }

        return flag == true ? Result.success(fileFullName) : Result.error("请仔细阅读红色字体部分信息！", null);

    }

    /**
     * 数据解析
     * @param fileNames 文件名
     * @return 返回结果集
     */
    @GetMapping("/exportFile/{fileNames}")
    public Result exportFile(@PathVariable("fileNames") String fileNames) {
        // 处理文件名，提取其中的最初文件名和最新文件名
        List<String> fileNameList = Arrays.asList(fileNames.split("@"));

        // 进行文件处理
        // 获得最初文件
        List<Plan> oldList = null;

        // 获得最新文件
        List<Plan> newList = null;

        // 遍历获取数据
        for(int i = 0; i < fileNameList.size(); i++) {
            String item = fileNameList.get(i);
            // 最初数据
            if (item.contains("old")) {
                oldList = planMap.get(item);
            }

            // 最新数据
            if (item.contains("new")) {
                newList = planMap.get(item);
            }
        }

        // 判定数据是否存在
        if (ObjectUtils.isEmpty(oldList)) { // 最初数据不存在
            return Result.error("请上传《最初》数据表格", null);
        }

        // 最新数据不存在
        if (ObjectUtils.isEmpty(newList)) {
            return Result.error("请上传「最新」数据表格", null);
        }

        return ProcessData(oldName, newName) == true ? Result.success("数据解析成功!") : Result.error("数据解析错误");
    }

    /**
     * 解析文件下载：滚动计划差异
     * @param response 响应对象
     */
    @GetMapping("/download")
    public void download(HttpServletResponse response) {
        try {
            DynamicChangeAnnoUtil.changeAnnoValueConvert();
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
        // 创建数据集合对象，存放计算后的数据值
        List<PlanVo> planVoList = new ArrayList<>();

        // 遍历新旧数据，完成数据之间的差异计算
        for (int i = 0; i < fullOldListData.size(); i++) {
            // 旧数据
            Plan oldPlan = fullOldListData.get(i);

            // 初值唯一项目
            String oldUnique = oldPlan.getProject() + oldPlan.getCustomerPartNo() + oldPlan.getTianHaiPartNo();

            for (int j = 0; j < fullNewListData.size(); j++) {
                // 新数据
                Plan newPlan = fullNewListData.get(j);

                // 创建最终对象
                PlanVo planVo = new PlanVo();

                // 新值唯一项目
                String newUnique = newPlan.getProject() + newPlan.getCustomerPartNo() + newPlan.getTianHaiPartNo();

                // 判定数据是否有存在一致的
                if (oldUnique.equals(newUnique)) {
                    // 项目名
                    planVo.setProject(oldPlan.getProject());
                    // 天海件号
                    planVo.setTianHaiPartNo(oldPlan.getTianHaiPartNo());
                    // 描述
                    planVo.setDescribe(oldPlan.getDescribe());

                    // 当月
                    planVo.setField1(newPlan.getField1());
                    planVo.setField2(oldPlan.getField1());

                    planVo.setDifference1(newPlan.getField1() - oldPlan.getField1());

                    planVo.setField3(newPlan.getField2());
                    planVo.setField4(oldPlan.getField2());

                    planVo.setDifference2(newPlan.getField2() - oldPlan.getField2());

                    planVo.setField5(newPlan.getField3());
                    planVo.setField6(oldPlan.getField3());

                    planVo.setDifference3(newPlan.getField3() - oldPlan.getField3());

                    planVo.setField7(newPlan.getField4());
                    planVo.setField8(oldPlan.getField4());

                    planVo.setDifference4(newPlan.getField4() - oldPlan.getField4());

                    planVo.setField9(newPlan.getField5());
                    planVo.setField10(oldPlan.getField5());

                    planVo.setDifference5(newPlan.getField5() - oldPlan.getField5());

                    planVo.setField11(newPlan.getField6());
                    planVo.setField12(oldPlan.getField6());

                    planVo.setDifference6(newPlan.getField6() - oldPlan.getField6());

                    planVoList.add(planVo);
                }
            }

        }
        EasyPoiUtil.exportExcel(planVoList, "滚动计划差异值计算(左：最新，右：最初)", "滚动计划", PlanVo.class, "滚动计划差异表.xls", response);
    }

    /**
     * 滚动计划差异明细
     * @param response 响应对象
     */
    @GetMapping("/downloadDetail")
    public void downloadDetail(HttpServletResponse response) {
        try {
            DynamicChangeAnnoUtil.changeAnnoValueDetail();
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
        // 创建数据集合对象，存放计算后的数据值
        List<PlanVo2> planVoList = new ArrayList<>();

        // 遍历新旧数据，完成数据之间的差异计算
        for (int i = 0; i < fullOldListData.size(); i++) {
            // 旧数据
            Plan oldPlan = fullOldListData.get(i);

            // 初值唯一项目
            String oldUnique = oldPlan.getProject() + oldPlan.getCustomerPartNo() + oldPlan.getTianHaiPartNo();

            for (int j = 0; j < fullNewListData.size(); j++) {
                // 新数据
                Plan newPlan = fullNewListData.get(j);

                // 创建最终对象
                PlanVo2 planVo = new PlanVo2();

                // 新值唯一项目
                String newUnique = newPlan.getProject() + newPlan.getCustomerPartNo() + newPlan.getTianHaiPartNo();

                // 判定数据是否有存在一致的
                if (oldUnique.equals(newUnique)) {

                    planVo.setTianHaiPartNo(oldPlan.getTianHaiPartNo());
                    // 描述
                    planVo.setDescribe(oldPlan.getDescribe());

                    // 增量
                    planVo.setField1(newPlan.getField1() - oldPlan.getField1());
                    planVo.setField2(newPlan.getField2() - oldPlan.getField2());
                    planVo.setField3(newPlan.getField3() - oldPlan.getField3());
                    planVo.setField4(newPlan.getField4() - oldPlan.getField5());
                    planVo.setField5(newPlan.getField5() - oldPlan.getField2());
                    planVo.setField6(newPlan.getField6() - oldPlan.getField6());

                    // 最新
                    planVo.setFieldNew1(newPlan.getField1());
                    planVo.setFieldNew2(newPlan.getField2());
                    planVo.setFieldNew3(newPlan.getField3());
                    planVo.setFieldNew4(newPlan.getField4());
                    planVo.setFieldNew5(newPlan.getField5());
                    planVo.setFieldNew6(newPlan.getField6());

                    // 最初
                    planVo.setFieldOld1(oldPlan.getField1());
                    planVo.setFieldOld2(oldPlan.getField2());
                    planVo.setFieldOld3(oldPlan.getField3());
                    planVo.setFieldOld4(oldPlan.getField4());
                    planVo.setFieldOld5(oldPlan.getField5());
                    planVo.setFieldOld6(oldPlan.getField6());

                    planVoList.add(planVo);
                }
            }

        }
        EasyPoiUtil.exportExcel(planVoList, "滚动计划差异明细（左：最新；右：最初）", "滚动计划差异明细", PlanVo2.class, "滚动计划差异明细表.xls", response);
    }

    /**
     * 模板文件下载
     * @param response 响应对象
     */
    @GetMapping("/templateDownloadOld")
    public void templateDownloadOld(HttpServletResponse response) {
        try {
            DynamicChangeAnnoUtil.changeAnnoValue();
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }

        List<Plan> plans = new ArrayList<>();
        EasyPoiUtil.exportExcel(plans, "滚动计划最初模板文件", "Sheet1", Plan.class, "滚动计划最初模板文件=old.xls", response);
    }

    @GetMapping("/templateDownloadNew")
    public void templateDownloadNew(HttpServletResponse response) {
        try {
            DynamicChangeAnnoUtil.changeAnnoValue();
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }

        List<Plan> plans = new ArrayList<>();
        EasyPoiUtil.exportExcel(plans, "滚动计划最新模板文件", "Sheet1", Plan.class, "滚动计划最新模板文件=new.xls", response);
    }


    /**
     * 数据处理方法
     * @return true 成功
     */
    private boolean ProcessData(String oldName, String newName) {
        // 创建接收 最新数据和 最初数据 的key值（项目值 + 天海件号值）
        List<String> oldAndNewList = new ArrayList<>();

        // 创建集合接收数据，保证key唯一
        LinkedHashSet<String> hashSet = null;

        // 创建key值唯一的集合
        List<String> keys = null;

        // 获得原始数据数据
        List<Plan> oldPlanList = planMap.get(oldName);

        // 获得最新数据
        List<Plan> newPlanList = planMap.get(newName);

        // 遍历最初数据(获得最初key值)
        oldPlanList.forEach(item -> {
            if (!ObjectUtils.isEmpty(item.getProject())) {
                oldAndNewList.add(item.getProject() + item.getCustomerPartNo() + item.getTianHaiPartNo());
            }
        });

        // 遍历最新数据(获得最新key值)
        newPlanList.forEach(item -> {
            if (!ObjectUtils.isEmpty(item.getProject())) {
                oldAndNewList.add(item.getProject() + item.getCustomerPartNo() + item.getTianHaiPartNo());
            }
        });

        // 获得唯一对象值
        hashSet = new LinkedHashSet<>(oldAndNewList);

        // 获得唯一键值集合
        keys = new ArrayList<>(hashSet);

        // 创建全新最初数据集
        List<Plan> fullOldList = new ArrayList<>();

        // 创建全新最新数据集
        List<Plan> fullNewList = new ArrayList<>();

        // 遍历keys值
        keys.forEach(item -> {
            fullOldList.add(Plan.builder().project(item).build());
            fullNewList.add(Plan.builder().project(item).build());
        });

        // 将所有最初数据值赋值给 keys
        fullOldList.forEach(item -> {
            // 遍历 最初数据
            for(Plan plan: oldPlanList) {
                // 判断数据
                if (item.getProject().equals(plan.getProject() + plan.getCustomerPartNo() + plan.getTianHaiPartNo())) { // 键值能够对应
                    // 项目名
                    item.setProject(plan.getProject());
                    // 天海件号
                    item.setTianHaiPartNo(plan.getTianHaiPartNo());
                    // 获得描述值
                    item.setDescribe(plan.getDescribe());
                    // 获得合计
                    item.setTotal(plan.getTotal());
                    // 获得备注
                    item.setRemark(plan.getRemark());
                    // 获得月份数据值
                    item.setField1(plan.getField1());
                    item.setField2(plan.getField2());
                    item.setField3(plan.getField3());
                    item.setField4(plan.getField4());
                    item.setField5(plan.getField5());
                    item.setField6(plan.getField6());
                }
            }
        });

        // 将所有最新数据值赋值给 keys
        fullNewList.forEach(item -> {
            // 遍历 最初数据
            for(Plan plan: newPlanList) {
                // 判断数据
                if (item.getProject().equals(plan.getProject() + plan.getCustomerPartNo() + plan.getTianHaiPartNo())) { // 键值能够对应
                    // 项目名
                    item.setProject(plan.getProject());
                    // 天海件号
                    item.setTianHaiPartNo(plan.getTianHaiPartNo());
                    // 获得描述值
                    item.setDescribe(plan.getDescribe());
                    // 获得合计
                    item.setTotal(plan.getTotal());
                    // 获得备注
                    item.setRemark(plan.getRemark());
                    // 获得月份数据值
                    item.setField1(plan.getField1());
                    item.setField2(plan.getField2());
                    item.setField3(plan.getField3());
                    item.setField4(plan.getField4());
                    item.setField5(plan.getField5());
                    item.setField6(plan.getField6());
                }
            }
        });


        // 循环遍历fullOldList集合，将其中的数据null值替换为0
        fullOldList.forEach(item -> {
            if (item.getField1() == null) {
                item.setField1(0);
            }

            if (item.getField2() == null) {
                item.setField2(0);
            }

            if (item.getField3() == null) {
                item.setField3(0);
            }

            if (item.getField4() == null) {
                item.setField4(0);
            }

            if (item.getField5() == null) {
                item.setField5(0);
            }

            if (item.getField6() == null) {
                item.setField6(0);
            }
        });

        // 循环遍历fullNewList集合，将其中的数据null值替换为0
        fullNewList.forEach(item -> {
            if (item.getField1() == null) {
                item.setField1(0);
            }

            if (item.getField2() == null) {
                item.setField2(0);
            }

            if (item.getField3() == null) {
                item.setField3(0);
            }

            if (item.getField4() == null) {
                item.setField4(0);
            }

            if (item.getField5() == null) {
                item.setField5(0);
            }

            if (item.getField6() == null) {
                item.setField6(0);
            }
        });

        // 最初和最新的完整数据fullOldList、fullNewList已完成
        fullOldListData = fullOldList;
        fullNewListData = fullNewList;

        return true;
    }
}